#include "dma_count.h"

#define pcm1_start_cnt_phy  0x43c0000c
#define pcm2_start_cnt_phy  0x43c00010
#define pcm_reset_phy       0x43c00024

volatile  unsigned long *pcm1_viraddr = NULL;
volatile  unsigned long *pcm2_viraddr = NULL;
volatile  unsigned long *pcm_reset_vir= NULL;

unsigned int axiadm_1_cnt=0;
unsigned int axiadm_2_cnt=0;

static void *axidma_cnt_mmap(unsigned long addr);
static void *devm_map(unsigned long addr, int len, int *phandle);

int axidma_cnt_init()
{
	pcm1_viraddr = axidma_cnt_mmap(pcm1_start_cnt_phy);
	pcm2_viraddr = axidma_cnt_mmap(pcm2_start_cnt_phy);
	pcm_reset_vir= axidma_cnt_mmap(pcm_reset_phy);

	if((pcm1_viraddr == NULL)||(pcm2_viraddr == NULL)||(pcm_reset_vir == NULL))
	{
		printf("pcm cnt reg mmap failed ! \n");
		return -1;
	}

	axiadm_1_cnt = get_axidma_cnt(1);
	axiadm_2_cnt = get_axidma_cnt(2);

	return 0;
}

void pcm_reset(void)
{
	*pcm_reset_vir = 1 ;
	usleep(1);
	*pcm_reset_vir = 0 ;
	usleep(1);
	axiadm_1_cnt=0;
	axiadm_2_cnt=0;
}

unsigned int get_axidma_cnt(unsigned char dma)
{
	if(dma == 1)
		return *pcm1_viraddr ;
	else if(dma == 2)
		return *pcm2_viraddr;
	else
		return 0;
}

static void *axidma_cnt_mmap(unsigned long addr)
{
	int fd = -1;
	return devm_map(addr, 1, &fd);
}

static void *devm_map(unsigned long addr, int len, int *phandle)
{
    off_t offset;
    void *map_base;

    if ((*phandle = open("/dev/mem", O_RDWR | O_SYNC)) == -1)
    {
	    printf("cannot open '/dev/mem'\n");
	    goto err_open;
    }

    /* offset for mmap() must be page aligned */
    offset = addr & ~(sysconf(_SC_PAGE_SIZE) - 1);

    map_base = mmap(NULL, len + addr - offset, PROT_READ | PROT_WRITE, MAP_SHARED, *phandle, offset);
    if (map_base == MAP_FAILED)
    {
	    printf("mmap failed\n");
	    goto err_mmap;
    }

    return map_base + addr - offset;
err_mmap:
	close(*phandle);
err_open:
	return NULL;
}
